package juc.topic;

/**
 * 三个线程交替顺序打印出 1-100
 * 第一个线程打印 3 的倍数，第二个线程打印 3n + 1 的数，第三个线程打印 3n + 2 的数（其中n是非负整数），同时使用一种机制来确保三个线程交替执行。
 */
public class AlternatePrintingThreeThreads {
    //当前需要打印的数
    private int num = 1;

    //同步对象锁
    private final Object lock = new Object();

    //需要使用的线程标志 0:3n 1:3n+1 2:3n+2
    private int turn = 0;


    public static void main(String[] args) {
        System.out.println(0 % 3);
        System.out.println(1 % 3);
        System.out.println(2 % 3);
        AlternatePrintingThreeThreads ap = new AlternatePrintingThreeThreads();
        new Thread(() -> {
            ap.print(1);
        }, "线程1").start();
        new Thread(() -> {
            ap.print(2);
        }, "线程2").start();
        new Thread(() -> {
            ap.print(3);
        }, "线程2").start();
    }


    public void print(int flag) {
        while (num <= 100) {
            synchronized (lock) {
                while ((turn % 3) != flag) {
                    try {
                        System.out.println(Thread.currentThread().getName() + "等待：");
                        lock.wait();
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
                if (num <= 100 && (num - 1) % 3 == flag) {
                    System.out.println(Thread.currentThread().getName() + "打印：" + num);
                    num++;
                    turn = (turn + 1) % 3;
                    lock.notifyAll();
                }
            }
        }
    }
}
